#include "xbelmodel.h"

int i_num_model = 1;        //отсчет номеров итемов от 1
int Vlosh_model = 100;     //вложенность - количество уровней
QString str_mes_posl_model, str_mes_dr_model;   //строки для сообщений показателей эргономичности при инициализации расчета
QString str_mes_pos_ves_model, str_mes_dr_ves_model;   //строки для сообщений показателей эргономичности при инициализации расчета

XbelModel::XbelModel(QObject *parent)
    : QStandardItemModel(parent)
{
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
    initialize();
    //load();
}

void XbelModel::initialize()
{
    setHorizontalHeaderLabels(QStringList() << tr("Название")
            << tr("Показатель \nэргономичности") << tr("Коэффициент \nвесомости") << tr("Номер \nсвойства"));
}

void XbelModel::load()
{
    QStandardItem *parent = invisibleRootItem();
    QList<QStandardItem*> items;
    items << new QStandardItem(tr("Номер свойства1"));
    items << new QStandardItem(tr("1"));
    items << new QStandardItem(tr("2"));
    items << new QStandardItem(tr("3"));
    parent->appendRow(items);
    items.clear();
    parent = invisibleRootItem()->child(0,0);
    items << new QStandardItem(tr("Номер свойства11"));
    items << new QStandardItem(tr("1"));
    items << new QStandardItem(tr("2"));
    items << new QStandardItem(tr("3"));
    parent->appendRow(items);
    items.clear();
    parent = invisibleRootItem();
    items << new QStandardItem(tr("Номер свойства2"));
    items << new QStandardItem(tr("1"));
    items << new QStandardItem(tr("2"));
    items << new QStandardItem(tr("3"));
    parent->appendRow(items);
    items.clear();
    parent = invisibleRootItem()->child(1,0);
    items << new QStandardItem(tr("Номер свойства21"));
    items << new QStandardItem(tr("1"));
    items << new QStandardItem(tr("2"));
    items << new QStandardItem(tr("3"));
    parent->appendRow(items);
    items.clear();
}

bool XbelModel::read(QFile *file)
{
    if(!file->isReadable())
    {
        if (!file->open(QFile::ReadOnly | QFile::Text)) {
            QMessageBox::warning(0, tr("Предупреждение Metodika"),
                                 tr("Невозможно прочитать файл %1:\n%2.")
                                 .arg(file->errorString()));
            return false;
        }
    }
    reader.setDevice(file);
    reader.readNext();
    while (!reader.atEnd()) {
        if (reader.isStartElement()) {
            if (reader.name() == "xbel") {
                readXbelElement();
            } else {
                QMessageBox::warning(0,tr("Предупреждение"),tr("Выбранный файл не xbel"));
                return false;
            }
        } else {
            reader.readNext();
        }
    }

    file->close();
    if (reader.hasError()) {
        QMessageBox::critical(0,tr("Ошибка"),tr("Ошибка при чтении файла"));
        return false;
    } else if (file->error() != QFile::NoError) {
        QMessageBox::critical(0,tr("Ошибка"),tr("Ошибка при чтении файла"));
        return false;
    }
    return true;
}

void XbelModel::readXbelElement()
{
    if(reader.attributes().value("version").toString() != tr("1.0"))
    {
        QMessageBox::warning(0,tr("Предупреждение"),tr("Версия файла не 1.0"));
        return;
    }
    reader.readNext();
    while (!reader.atEnd()) {
        if (reader.isEndElement()) {
            reader.readNext();
            break;
        }

        if (reader.isStartElement()) {
            if (reader.name() == "folder") {
                readFolderElement(invisibleRootItem());
            } else {
                skipUnknownElement();
            }
        } else {
            reader.readNext();
        }
    }
}

void XbelModel::readFolderElement(QStandardItem *parent)
{
    QList<QStandardItem*> items;
    items << new QStandardItem(reader.attributes().value("title").toString());
    items << new QStandardItem(reader.attributes().value("value_ergo").toString());
    items << new QStandardItem(reader.attributes().value("value_ves").toString());
    items << new QStandardItem(reader.attributes().value("value_number").toString());
    items << new QStandardItem(reader.attributes().value("folded").toString());
    parent->appendRow( items );
    //qDebug() << items[0]->text();

    reader.readNext();
    while (!reader.atEnd()) {
        if (reader.isEndElement()) {
            reader.readNext();
            break;
        }

        if (reader.isStartElement()) {
            if (reader.name() == "folder") {
                int row = 0;
                for(int i = 0; parent->child(i,0) != NULL; i++)
                {
                    row = i;
                }
                readFolderElement(parent->child(row,0));
        } else {
                skipUnknownElement();
            }
        } else {
            //qDebug() << "nostart";
            reader.readNext();
        }
    }
    //qDebug() << "endwhile";
}


void XbelModel::skipUnknownElement()
{
    //qDebug() << "skip";
    reader.readNext();
    while (!reader.atEnd()) {
        if (reader.isEndElement()) {
            reader.readNext();
            break;
        }

        if (reader.isStartElement()) {
            skipUnknownElement();
        } else {
            reader.readNext();
        }
    }
}

bool XbelModel::write(QFile *file)
{
    QXmlStreamWriter xmlWriter(file);
    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("xbel");
    xmlWriter.writeAttribute(tr("version"),tr("1.0"));

    writeFolderElement(&xmlWriter, invisibleRootItem(),invisibleRootItem(),invisibleRootItem(),invisibleRootItem(),invisibleRootItem());

    xmlWriter.writeEndDocument();
    file->close();
    if(file->error())
    {

       return false;
    }
    return true;
}

void XbelModel::writeFolderElement(QXmlStreamWriter *xmlWriter, QStandardItem *root, QStandardItem *root1,QStandardItem *root2,QStandardItem *root3,QStandardItem *root4)
{
    if (root != invisibleRootItem()) {
        xmlWriter->writeStartElement("folder");
        xmlWriter->writeAttribute("title", root->text());
        xmlWriter->writeAttribute("value_ergo", root1->text());
        xmlWriter->writeAttribute("value_ves", root2->text());
        xmlWriter->writeAttribute("value_number", root3->text());
        xmlWriter->writeAttribute("folded", root4->text());
    }
    for (int row = 0; row < root->rowCount(); ++row)
        writeFolderElement(xmlWriter, root->child(row, 0), root->child(row, 1), root->child(row, 2), root->child(row, 3), root->child(row, 4));
    if (root != invisibleRootItem())
        xmlWriter->writeEndElement();
}

void XbelModel::createItem(QStandardItem *parent)
{
    QList<QStandardItem*> items;
    items << new QStandardItem("title");
    items << new QStandardItem("value_ergo");
    items << new QStandardItem("value_ves");
    items << new QStandardItem("value_number");
    items << new QStandardItem("folded");
    parent->appendRow(items);
}

bool XbelModel::slot_insertItem(bool child)
{
    QMessageBox::about(0,tr("Предупреждение"), tr("Слот не прописан"));
    return true;
}

bool XbelModel::slot_deleteItem(QStandardItem *item, int row)
{
    item->parent()->removeRow(row);
    return true;
}

bool XbelModel::slot_raschet()
{
    str_mes_pos_ves_model.clear();
    str_mes_posl_model.clear();
    str_mes_dr_model.clear();

    ras_init(invisibleRootItem());        //Приводим к нормальному виду со значениями только в последних child


        if(!str_mes_posl_model.isNull())  {
            QMessageBox::about(0,tr("Предупреждение"),tr("Не заполнен показатель эргономичности элемента ").append(str_mes_posl_model));
        return false;
        }
        if(!str_mes_dr_model.isNull())    {
            QMessageBox::about(0,tr("Предупреждение"),tr("Заполнен показатель эргономичности элемента ").append(str_mes_dr_model).append(tr(" который должен рассчитываться")));
        return false;
        }
        if(!str_mes_pos_ves_model.isNull())  {
            QMessageBox::about(0,tr("Предупреждение"),tr("Не заполнен коэффициент весомости элемента ").append(str_mes_pos_ves_model));
        return false;
        }

        for(int i =0; i < Vlosh_model; ++i)
        {
            ras_func(invisibleRootItem()->child(0,0),invisibleRootItem()->child(0,1));            //расчет value
        }

        //расчет number
            slot_ras_number(invisibleRootItem()->child(0,0),invisibleRootItem()->child(0,3));

    return true;
}

void XbelModel::ras_init(QStandardItem *item)
{
    for(int i =0; i < item->rowCount(); ++i)
    {
        //проверяем элементы на заполненность их показателя весомости
        if(item->child(i,2)->text().isEmpty())  {
            str_mes_pos_ves_model.append(item->child(i,0)->text()).append(" ");
        }
        //проверить последние child на заполненность их показателя эргономичности
        if(item->child(i,0)->child(0,0) == NULL)
        {
            if(item->child(i,1)->text().isEmpty())  {
                str_mes_posl_model.append(item->child(i,0)->text()).append(" ");
            }
        }
        else
        {
            if(!item->child(i,1)->text().isEmpty())
            {
                str_mes_dr_model.append(item->child(i,0)->text()).append(" ");
            }
        }
        ras_init(item->child(i,0));       //рекурсия
    }
}

void XbelModel::ras_func(QStandardItem *item,QStandardItem *item1)
{
        QString mas_ergo[100];     //количество дочерних элементов одного элемента
        QString mas_ves[100];

    for(int i =0; i < item->rowCount(); ++i)
    {
        if(!item->child(i,1)->text().isEmpty())            //то это элементы последние
        {
            mas_ergo[i] = item->child(i,1)->text();
            mas_ves[i] = item->child(i,2)->text();
        }
        ras_func(item->child(i),item->child(i,1));               //рекурсия
    }

        float value = 0;

    for(int i =0; !mas_ergo[i].isNull(); i++)         //формула которая плюсует элементы в value
    {
        value = value + mas_ergo[i].toFloat()*mas_ves[i].toFloat();
    }

    if(!mas_ergo[0].isNull())
    {
        item1->setText(QString::number(value));    //записываем значение в итем
    }

}

void XbelModel::slot_ras_number(QStandardItem *item, QStandardItem *item3)
{
    for(int i =0; i < item->rowCount(); ++i)
        slot_ras_number(item->child(i),item->child(i,3));

    item3->setText(QString::number(i_num_model));    //записываем значение в итем
    ++i_num_model;
}

bool XbelModel::slot_new(QFile *file_new)
{
    QXmlStreamWriter xmlWriter(file_new);
    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("xbel");
    xmlWriter.writeAttribute(tr("version"),tr("1.0"));

    xmlWriter.writeStartElement("folder");
    xmlWriter.writeAttribute("title",tr("Эргономичность"));
    xmlWriter.writeAttribute("value_ergo","");
    xmlWriter.writeAttribute("value_ves","");
    xmlWriter.writeAttribute("value_number","");
    xmlWriter.writeAttribute("folded","");

    xmlWriter.writeEndDocument();

    file_new->close();

    if(file_new->error())
    {
       return false;
    }

    if(!read(file_new))
    return false;

    return true;
}
